﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using MongoDB.Driver;
using YmtAuth.AppService.Safe;
using YmtAuth.Common.Extend;
using YmtAuth.Domain.DomainService;
using YmtAuth.Domain.EventHistory;
using YmtAuth.Domain.Model.BlacklistUser;
using YmtAuth.Domain.Repository;
using YmtAuth.Repository.MSSQL;
using YmtSystem.CrossCutting;
using YmtAuth.Domain.Model.Safe;
using YmtAuth.Dto;
using YmtAuth.Domain.Model.LoginAuth;
using YmtAuth.Common.Cache;
using Ymatou.User.Dto.Auth;

namespace YmtAuth.AppService
{
    /// <summary>
    /// 用户白名单
    /// </summary>
    public class WhiteListAppService
    {
        private static readonly IUserLoginBillsRepository UlcRepo = LocalServiceLocator.GetService<IUserLoginBillsRepository>();
        private static readonly IUserWhitelistRepository userWhitelistRepo = LocalServiceLocator.GetService<IUserWhitelistRepository>();

        private static readonly LocalCache2<int, bool> WhiteUserCache = new LocalCache2<int, bool>();  

        /// <summary>
        /// 判断用户是否是白名单用户
        /// </summary>
        /// <param name="loginId"></param>
        /// <returns></returns>
        public static ResponseData<UserLoginBill> IsWhiteUser(LoginAuthRequestDto dto)
        {
            if (!CheckWhiteUserIsEnable()) return ResponseData<UserLoginBill>.CreateFail(null, "100", "用户白名单开关关闭");

            ResponseData<UserLoginBill> res = null;
            try
            {
                var query = UserLoginAuthSpecifications.MatchLoginKey(dto.LoginId);
                var ulc = UlcRepo.FindOne(query, true);

                if (ulc != null)
                {
                    int userId = ulc.UserId;

                    bool isWhiteUser = (bool)WhiteUserCache.GetOrAdd(userId, uid => new LocalCache2<int, bool>._CacheItem
                    {
                        Value = userWhitelistRepo.First(new { UserId = uid }) != null,
                        ExpiredTime = TimeSpan.FromMinutes(3)
                    });

                    if (isWhiteUser)
                    {
                        res = ResponseData<UserLoginBill>.CreateSuccess(ulc, "OK");
                        YmatouLoggingService.Debug("白名单用户，WhiteUser； userId: {0}, clientIp: {1}, source: {2}, login id: {3}, deviceId: {4}",
                            ulc.UserId, dto.ClientIp, dto.SourceType, dto.LoginId, dto.DeviceId);
                    }
                    else
                    {
                        res = ResponseData<UserLoginBill>.CreateFail(ulc, "300", "此用户不在白名单");
                    }
                }
                else
                {
                    res = ResponseData<UserLoginBill>.CreateFail(null, "500", "用户ID不存在");
                }
            }
            catch (Exception ex)
            {
                YmatouLoggingService.Error("检测用户白名单出现异常, IsWhiteUser; loginId: {0}, ex: {1}", dto.LoginId, ex);
                res = ResponseData<UserLoginBill>.CreateFail(null, "400", ex.Message);
            }

            return res;
        }

        /// <summary>
        /// 是否启用用户白名单
        /// </summary>
        /// <returns></returns>
        private static bool CheckWhiteUserIsEnable()
        {
            var enableUserWhitelist = ConfigurationManager.AppSettings["EnableUserWhitelist"];
            if (string.IsNullOrEmpty(enableUserWhitelist) || enableUserWhitelist == "0")
            {
                return false;
            }
            return true;
        }
    }
}
